#include "Global_Function.h"
#include "JsonRpcServerMethod.h"
#include "JsonRpcServer.h"
#include "JsonRpcException.h"

namespace JsonRpc {


  JsonRpcServerMethod::JsonRpcServerMethod(std::string const& name, JsonRpcServer* server)
  {
    _name = name;
    _server = server;
    if (_server) _server->addMethod(this);
  }

  JsonRpcServerMethod::~JsonRpcServerMethod()
  {
    if (_server) _server->removeMethod(this);
  }
  
  namespace Wrapper {
        WrapperBase::WrapperBase(JsonRpcServer* s, std::string const& methodName, std::string const& help, const void *context) 
            : JsonRpcServerMethod(methodName, s), _help(help), _context(context) 
        {
        }
        void WrapperBase::_checkArgc(Json::Value& params, unsigned int expected)
        {
        if(!params.isArray())
            throw JsonRpcException(_name + ": Invalid argument (expected an array)");

        if(params.size() > expected)
            throw JsonRpcException(_name + ": Invalid argument(too many arguments)");

        if(params.size() < expected)
            throw JsonRpcException(_name + ": Invalid argument(too fewer arguments)");

        }

        void WrapperBase::_reportTypeError(int index, std::string s)
        {
            char buf[1024];

            snprintf(buf, sizeof(buf), ": Invalid argument type at point %d, expected type:%s", index +1, s.c_str());
            throw  JsonRpcException(_name + buf);
        }
        void WrapperBase::_checkType(Json::Value & params, int index, int *)
        {
          if(!params[index].isInt()) _reportTypeError(index, "integral");
        }
        void WrapperBase::_checkType(Json::Value & params, int index, unsigned int *)
        {
          if(!params[index].isConvertibleTo(Json::uintValue)) _reportTypeError(index, "unsigned integral");
        }
        void WrapperBase::_checkType(Json::Value & params, int index, double *)
        {
          if(!params[index].isConvertibleTo(Json::realValue)) _reportTypeError(index, "double");
        }
        void WrapperBase::_checkType(Json::Value & params, int index, std::string *)
        {
          if(!params[index].isString()) _reportTypeError(index, "string");
        }
        void WrapperBase::_checkType(Json::Value & params, int index, const char **)
        {
          if(!params[index].isString()) _reportTypeError(index, "string");
        }

        void WrapperBase::_checkType(Json::Value & params, int index, bool *)
        {
          if(!params[index].isConvertibleTo(Json::booleanValue)) _reportTypeError(index, "boolean");
        }

        void WrapperBase::_checkType(Json::Value & params, int index, Json::Value *)
        {
        }

  } // namespace Wrapper
} // namespace JsonRpc
